<!--
  1.实现一个table，table中的数据来源于form表单，可以对当前行进行编辑、浏览、删除功能
    1.1 编辑功能，可以修改当前行的数据，修改完成后，点击保存按钮，将当前行的数据保存到table中
    1.2 浏览功能，可以查看当前行的数据
    1.3 删除功能，可以删除当前行
  2.新增功能，可以将当前form的数据保存到table中
-->
<template>
  <div>
    <el-card style="margin: 10px">
      <!-- 在table中对form进行编辑   -->
      <el-form :model="modelData" ref="modelData">
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="表单信息" prop="formInfo" :rules="rules.formInfo">
              <el-input v-model="modelData.formInfo"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="代码信息" prop="formCode" :rules="rules.formCode">
              <complex-input :text.sync="modelData.formText" :value.sync="modelData.formCode"/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-table :data="tableData" style="width: 100%">
          <el-table-column prop="username" label="用户" width="">
          </el-table-column>
          <el-table-column prop="password" label="密码" width="">
          </el-table-column>
          <el-table-column prop="age" label="年龄" width="">
          </el-table-column>
          <el-table-column prop="sex" label="性别" width="">
          </el-table-column>
          <el-table-column label="Operations">
            <template slot-scope="scope">
              <el-button v-if="!scope.row.editable" size="" @click="handleEdit(scope.$index, scope.row)">编辑
              </el-button>
              <el-button v-else size="" @click="cancel(scope.$index, scope.row)">取消</el-button>
              <el-button size="" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
        <el-form :model="tableForm" :rules="rules" ref="tableForm">
          <el-row type="flex-wrap" :gutter="20">
            <el-col :span="8">
              <el-form-item label="用户" prop="username">
                <el-input v-model="tableForm.username"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="密码" prop="password">
                <el-input v-model="tableForm.password"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="年龄" prop="age">
                <el-input v-model="tableForm.age"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="性别" prop="sex">
                <el-input v-model="tableForm.sex"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
        <el-button style="margin: 10px 0;width: 100%;border: 1px dashed #DCDFE6" type="default" @click="addRow">保存
        </el-button>
      </el-form>
      <el-button style="margin: 10px 0;width: 100%;border: 1px dashed #DCDFE6" type="default" @click="submitForm">提交
      </el-button>
    </el-card>
  </div>
</template>

<script>
import ComplexInput from '@/views/form/components/ComplexInput.vue'

export default {
  components: { ComplexInput },
  data() {
    return {
      tableData: [],
      modelData: {
        formInfo: '',
        formCode: '',
        formText: ''
      },
      tableForm: {
        username: '',
        password: '',
        age: '',
        sex: '',
        // 是否处于编辑状态
        editable: false,
        key: ''
      },
      rules: {
        formInfo: [{ required: true, message: '表单信息不能为空', trigger: 'blur' }],
        formCode: [{ required: true, message: '代码信息不能为空', trigger: 'blur' }],
        username: [{ required: true, message: '用户名不能为空', trigger: 'blur' }],
        password: [{ required: true, message: '密码不能为空', trigger: 'blur' }],
        age: [{ required: true, message: '年龄不能为空', trigger: 'blur' }],
        sex: [{ required: true, message: '性别不能为空', trigger: 'blur' }]
      }
    }
  },
  mounted() {
    // 测试 reset能否还原对象，是可以的
    console.log({ ...this.tableForm })
    this.resetForm('tableForm')
    console.log({ ...this.tableForm })
  },
  methods: {
    addRow() {
      console.log('form', this.tableForm)
      // 保存信息并重置表单
      this.$refs['tableForm'].validate(valid => {
        if (valid) {
          console.log('add row', { ...this.tableForm })
          const curr = this.tableData.find(e => e.editable)
          // 找到处于编辑的值，如果有，则代表是修改
          if (curr) {
            Object.assign(curr, this.tableForm)
          } else {
            // 否则是新增状态，或者是删除过当前编辑的值，都为新增
            // 添加对象
            const data = { ...this.tableForm }
            this.tableData.push(data)
            console.log(data.editable)
          }
          // 这个resetForm好像是恢复到上一次form的值，而不是最开始的值
          this.resetForm('tableForm')
          // 这里要重置非表单属性，非表单绑定属性不能还原
          this.tableForm.editable = false
          console.log('after reset', { ...this.tableForm })
        } else {
          this.$message.error('请填写完整信息')
        }
      })
    },
    resetForm(formRef) {
      this.$refs[formRef].resetFields()
    },
    /**
     * 将数据赋值给表单，如果保存，将数据回写table，取消则还原数据
     * @param index
     * @param row
     */
    handleEdit(index, row) {
      // table中的数据
      // const td = this.tableData.find((e, idx) => idx === index);
      // todo >> 这里是true，说明当前传入的row就是table中的对象本身
      // console.log('是否是元数据', td === row);
      // 编辑前将其他的先取消编辑
      this.tableData.forEach(e => {
        e.editable = false
      })
      // 保存原始数据 表单是行的原始数据，这里存的是tableData的原始数据，即使在删除状态下，row.editable也是false
      this.tableForm = { ...row }
      // 编辑行时，存备份数据（可以省去？），并且设置编辑状态
      // row._data = {...row}
      row.editable = true
      console.log('edit', row, this.tableData[index], this.tableData[index] === row, this.tableForm)
    },
    // 还原数据(是否可以省略？)，重置表单
    cancel(index, row) {
      // 这种直接赋值，不能响应式
      // row = row._data
      // 方式1：这种方式更新对象是响应式的
      // Object.assign(row, row._data)
      // row._data = null;
      // 方式2：更新table数据
      // row = row._data
      // row._data = null;
      // this.$set(this.tableData, index, row);
      this.tableData[index].editable = false
      this.resetForm('tableForm')
      console.log('cancel', row, this.tableData[index])
    },
    handleDelete(index, row) {
      console.log(index, row)
      this.tableData.splice(index, 1)
    },
    // 提交表单，重置主表单和子table
    submitForm() {
      console.log('submitForm', { ...this.modelData }, this.tableData)
      this.resetForm('modelData')
      this.tableData = []
    }
  }
}
</script>

<style scoped>
/* 可选的样式调整 */
</style>
